package org.ofbiz.autoconfig.auto;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javolution.util.FastMap;

import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.jdbc.SQLProcessor;
import org.ofbiz.entity.model.ModelGroupReader;

public class EntitySQLProcessor {

    public static Map executeQuery(Delegator delegator, Map service_context) {
	// TODO Auto-generated method stub
	if (UtilValidate.isEmpty(service_context.get("sqlCommand")))
	    return FastMap.newInstance();
	String sqlCommand = (String) service_context.get("sqlCommand");
	String selGroup = "org.ofbiz";
	if (UtilValidate.isNotEmpty(service_context.get("selGroup")))
	    selGroup = (String) service_context.get("selGroup");
	int rowLimit = 9999;
	if (UtilValidate.isNotEmpty(service_context.get("rowLimit")))
	    rowLimit = (Integer) service_context.get("rowLimit");
	return executeQuery(delegator, sqlCommand, selGroup, rowLimit);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Map executeQuery(Delegator delegator, String sqlCommand, String selGroup, int rowLimit) {
	Map result = new HashMap();

	String resultMessage = "";
	List columns = new ArrayList();
	List records = new ArrayList();
	ModelGroupReader mgr = delegator.getModelGroupReader();
	Set groups = mgr.getGroupNames(delegator.getDelegatorName());

	if (UtilValidate.isNotEmpty(sqlCommand) && UtilValidate.isNotEmpty(selGroup)) {
	    SQLProcessor du = new SQLProcessor(delegator, delegator.getGroupHelperInfo(selGroup));
	    ResultSet rs = null;
	    try {
		if (sqlCommand.toUpperCase().startsWith("SELECT")) {
		    rs = du.executeQuery(sqlCommand);
		    if (UtilValidate.isNotEmpty(rs)) {
			ResultSetMetaData rsmd = rs.getMetaData();
			int numberOfColumns = rsmd.getColumnCount();
			for (int i = 1; i <= numberOfColumns; i++) {
			    columns.add(rsmd.getColumnName(i));
			}
			boolean rowLimitReached = false;
			while (rs.next()) {
			    if (records.size() >= rowLimit) {
				resultMessage = "Returned top $rowLimit " + rowLimit + " rows.";
				rowLimitReached = true;
				break;
			    }
			    List record = new ArrayList();
			    for (int j = 1; j <= numberOfColumns; j++) {
				record.add(rs.getObject(j));
			    }
			    records.add(record);
			}
			resultMessage = "Returned " + (rowLimitReached ? "top " + rowLimit : "" + records.size())
				+ " rows.";
			rs.close();
		    }
		} else {
		    du.prepareStatement(sqlCommand);
		    int numOfAffectedRows = du.executeUpdate();
		    resultMessage = "Affected $numOfAffectedRows " + numOfAffectedRows + " rows.";
		}
	    } catch (Exception exc) {
		resultMessage = exc.getMessage();
	    }
	}

	result.put("groups", groups);
	result.put("resultMessage", resultMessage);
	result.put("columns", columns);
	result.put("records", records);
	return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
	// TODO Auto-generated method stub

    }

}
